package edu.indiana.application;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;


/**
 * This class handles the UI. It has a CycTalk object and passes values to the functions and get the output.
 */
public class UserInterface implements ActionListener,DocumentListener{

	JFrame frame;
	JPanel emptyPanel;
	JPanel status;
	JPanel argumentsPanel;
	JButton createConceptButton;
	JComboBox functionListBox;
	JComboBox conceptListBox;
	JLabel functionLabel;
	JTextField concept;
	JTextField associatedConcept;
	JLabel conceptLabel;
	JTextField concept2;
	JLabel conceptLabel2;
	JLabel associatedConceptLabel;
	JLabel suggestedConceptLabel;
	static JTextArea statusText;
	CycTalk talkToCyc;
	JRadioButton createConstantButton;
	JRadioButton createConstantAndFunctionButton;
	JPanel createConstantPanel;
	JPanel createConstantAndFunctionPanel;
	JLabel microTheoryLabel;
	JLabel commentLabel;
	JTextField microTheory;
	JTextField comment;
	GridBagConstraints c;
	JLabel numberOfArgsLabel;
	JTextField numberOfArgs;
	JLabel argTypeLabel;
	List<JTextField> argTypes;
	JLabel functionTypeLabel;
	JComboBox functionTypeListBox;
	JButton createConceptAndFunctionButton;

	JScrollPane scroller;

	static String constantString = "Constant";
	static String constantAndFunctionString = "Function";

	List<String> conceptNames;

	public UserInterface() {
		List<String> functionValues = new ArrayList<String>();
		functionValues.add("isA");
		functionValues.add("genls");

		List<String> functionTypes = new ArrayList<String>();
		functionTypes.add("function");
		functionTypes.add("predicate");

		frame = new JFrame("Opencyc");
		emptyPanel = new JPanel();
		argumentsPanel = new JPanel();
		scroller = new JScrollPane(argumentsPanel);
		scroller.setPreferredSize(new Dimension(200,200));


		status = new JPanel();
		statusText = new JTextArea(2,40); 
		statusText.setEditable(false);
		statusText.setLineWrap(true);

		status.add(statusText);

		createConstantPanel = new JPanel(new GridLayout(0,2,10,10));
		createConstantAndFunctionPanel = new JPanel(new GridLayout(0,2,10,10));

		functionListBox = new JComboBox(functionValues.toArray());
		conceptListBox = new JComboBox();
		concept = new JTextField(20);
		concept2 = new JTextField(20);
		associatedConcept = new JTextField(20);
		conceptLabel = new JLabel("Concept");
		conceptLabel2 = new JLabel("Concept");
		associatedConceptLabel = new JLabel("Concept to associate");
		createConceptButton = new JButton("Create Concept");
		functionLabel = new JLabel("Function Type");
		suggestedConceptLabel = new JLabel("Suggested Concept");
		microTheoryLabel = new JLabel("MicroTheory");
		microTheory = new JTextField(20);
		commentLabel = new JLabel("Comment");
		comment = new JTextField(50);
		numberOfArgsLabel = new JLabel("Number of Arguments");
		numberOfArgs = new JTextField(20);
		argTypeLabel = new JLabel("Argument Type");
		argTypes = new ArrayList<JTextField>();
		functionTypeLabel = new JLabel("Function Type");
		functionTypeListBox = new JComboBox(functionTypes.toArray());
		createConceptAndFunctionButton = new JButton("Create Concept&Function");

		createConstantButton = new JRadioButton("Create Concept Only");
		createConstantAndFunctionButton = new JRadioButton("Create Concept and Function");

		numberOfArgs.getDocument().addDocumentListener(this);

		c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.9;
		c.weighty = 0.1;


		createConstantButton.setActionCommand(constantString);
		createConstantAndFunctionButton.setActionCommand(constantAndFunctionString);

		ButtonGroup group = new ButtonGroup();
		group.add(createConstantButton);
		group.add(createConstantAndFunctionButton);

		createConstantButton.addActionListener(this);
		createConstantAndFunctionButton.addActionListener(this);

		JPanel radioPanel = new JPanel(new GridLayout(0, 1));
		radioPanel.setSize(100,100);
		radioPanel.add(createConstantButton);
		radioPanel.add(createConstantAndFunctionButton);


		frame.setLayout(new GridBagLayout());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		c.fill = GridBagConstraints.VERTICAL;
		c.gridx = 0;
		c.gridy = 0;
		c.anchor = GridBagConstraints.FIRST_LINE_START;

		frame.add(radioPanel,c);

		c.gridx = 0;
		c.gridy = 1;
		c.weighty = 0.5;
		frame.add(emptyPanel,c);

		c.anchor = GridBagConstraints.LAST_LINE_START;
		c.gridx = 0;
		c.gridy = 5;
		frame.add(status,c);
		c.anchor = GridBagConstraints.LINE_START;

		createConstantPanel.add(conceptLabel);
		createConstantPanel.add(concept);
		createConstantPanel.add(associatedConceptLabel);
		createConstantPanel.add(associatedConcept);
		createConstantPanel.add(suggestedConceptLabel);
		createConstantPanel.add(conceptListBox);
		createConstantPanel.add(functionLabel);
		createConstantPanel.add(functionListBox);
		createConstantPanel.add(microTheoryLabel);
		createConstantPanel.add(microTheory);
		createConstantPanel.add(commentLabel);
		createConstantPanel.add(comment);
		createConstantPanel.add(createConceptButton);
		createConceptButton.addActionListener(this);

		createConstantAndFunctionPanel.add(conceptLabel2);
		createConstantAndFunctionPanel.add(concept2);
		createConstantAndFunctionPanel.add(numberOfArgsLabel);
		createConstantAndFunctionPanel.add(numberOfArgs);
		createConstantAndFunctionPanel.add(argTypeLabel);
		createConstantAndFunctionPanel.add(scroller);
		createConstantAndFunctionPanel.add(functionTypeLabel);
		createConstantAndFunctionPanel.add(functionTypeListBox);
		createConstantAndFunctionPanel.add(createConceptAndFunctionButton);
		createConceptAndFunctionButton.addActionListener(this);

		frame.setSize(500, 700);

		frame.setVisible(true);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getActionCommand().equalsIgnoreCase(constantAndFunctionString)) {
			c.insets = new Insets(10,10,10,10);
			c.gridx = 0;
			c.gridy = 2;
			c.weighty = 0.5;
			frame.remove(createConstantPanel);
			frame.add(createConstantAndFunctionPanel,c);
			frame.validate();
			frame.repaint();
		} else if(e.getActionCommand().equalsIgnoreCase(constantString)) {
			c.insets = new Insets(10,10,10,10);
			c.gridx = 0;
			c.gridy = 1;
			c.weighty = 0.5;
			frame.remove(createConstantAndFunctionPanel);
			frame.add(createConstantPanel,c);
			frame.validate();
			frame.repaint();
		} else if(e.getSource().equals(createConceptButton)){
			System.out.println("Concept submit button presses");
			new Thread(new Runnable(){ 
				@Override
				public void run() {
					talkToCyc = new CycTalk(Application.userInterface);
					if(conceptListBox.getItemCount()==0){
						if(!talkToCyc.isAConstant(associatedConcept.getText())){
							Object[] conceptList = talkToCyc.queryTerm(associatedConcept.getText());
							conceptNames = new ArrayList<String>();
							for(Object conceptName : conceptList){
								conceptListBox.addItem(conceptName.toString());
							}
						}
					}else {
						associatedConcept.setText(conceptListBox.getSelectedItem().toString());
					}
					try {
						talkToCyc.createConstant(concept.getText(), comment.getText(), microTheory.getText(), associatedConcept.getText(), functionListBox.getSelectedItem().toString());
					} catch (Exception e) {
						statusText.setText(e.getMessage());
					}
				} }).start();
		} else if(e.getSource().equals(createConceptAndFunctionButton)){
			System.out.println("Concept And Function submit button presses");
			new Thread(new Runnable(){ 
				@Override
				public void run() {
					talkToCyc = new CycTalk(Application.userInterface);
					List<String> argumentValues = new ArrayList<String>();
					for (JTextField field:argTypes) {
						argumentValues.add(field.getText());
					}
					if(functionTypeListBox.getSelectedItem().toString().equalsIgnoreCase("function")){
						talkToCyc.createFunction(concept2.getText(), Integer.parseInt(numberOfArgs.getText()),
								argumentValues);
					}else if(functionTypeListBox.getSelectedItem().toString().equalsIgnoreCase("predicate")){
						talkToCyc.createPredicate(concept2.getText(), Integer.parseInt(numberOfArgs.getText()),
								argumentValues);
					}
				} }).start();
		}
	}

	@Override
	public void changedUpdate(DocumentEvent e) {
		// Do nothing
	}

	@Override
	public void insertUpdate(DocumentEvent e) {
		int n = Integer.parseInt(numberOfArgs.getText());
		for(int i=0;i<n;i++){
			argTypes.add(new JTextField(10));
		}
		for(int i=0;i<n;i++){
			argumentsPanel.add(argTypes.get(i));
		}
		frame.validate();
		frame.repaint();
	}

	@Override
	public void removeUpdate(DocumentEvent e) {
		// Do nothing
	}
}

